'/
' GUI Library
' Written by Anton Berlin, 2010.
' 
' =========================================================================
' 
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU Lesser General Public License as published
' by the Free Software Foundation; either version 3 of the License.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU Lesser General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'/

superstrict

import BRL.GLMax2D
import Pub.Glew

import "../drawutil/drawutil.bmx"

import "GUI_Window.bmx"
import "GUI_Field.bmx"
import "GUI_Text.bmx"
import "GUI_Button.bmx"
import "GUI_Image.bmx"
import "GUI_Checkbox.bmx"
import "GUI_Form.bmx"
import "GUI_List.bmx"
import "GUI_Menu.bmx"
import "GUI_MenuItem.bmx"
import "GUI_Slider.bmx"

type GUI_Layer

	'// -------------------------------------------------------------------------------------------------------------
	'// Draw this layer.
	'// -------------------------------------------------------------------------------------------------------------
	method draw()
	
		if (not m_visible) ..
			return;
		
		if (m_useBackgroundColor) then
		
			drawutil.setColorInit(m_backgroundColorR, m_backgroundColorG, m_backgroundColorB);
			drawutil.setAlphaInit(m_transparency);
			drawRect(0, 0, m_resX, m_resY);
			drawutil.resetColor();
			drawutil.resetAlpha();
		
		end if
		
		for local gadget:GUI_Gadget = eachin m_gadgetList
		
			select (gadget.m_type)
			
				case GADGET_WINDOW
					GUI_Window(gadget).draw();
				case GADGET_BUTTON
					GUI_Button(gadget).draw();
				case GADGET_TEXT
					GUI_Text(gadget).draw();
				case GADGET_IMAGE
					GUI_Image(gadget).draw();
				case GADGET_FIELD
					GUI_Field(gadget).draw();
				case GADGET_FORM
					GUI_Form(gadget).draw();
				case GADGET_CHECKBOX
					GUI_Checkbox(gadget).draw();
				case GADGET_LIST
					GUI_List(gadget).draw();
				case GADGET_MENU
					GUI_Menu(gadget).draw();
				case GADGET_SLIDER
					GUI_Slider(gadget).draw();
			
			end select
		
		next
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a gadget from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getGadget:GUI_Gadget(name:string)
	
		return GUI_Gadget(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a window to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addWindow(name:string, visible:byte = false)
	
		local window:GUI_Window = new GUI_Window;
		
		window.m_type = GADGET_WINDOW;
		window.m_name = name;
		window.m_visible = visible;
		window.m_layer = self;
		
		m_gadgetList.addLast(window);
		m_gadgetListReversed.addFirst(window);
		m_gadgetMap.insert(name, window);
		
		window.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a window from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getWindow:GUI_Window(name:string)
	
		return GUI_Window(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a field to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addField(name:string, visible:byte = false)
	
		local fld:GUI_Field = new GUI_Field;
		
		fld.m_type = GADGET_FIELD;
		fld.m_name = name;
		fld.m_visible = visible;
		fld.m_layer = self;
		
		m_gadgetList.addLast(fld);
		m_gadgetListReversed.addFirst(fld);
		m_gadgetMap.insert(name, fld);
		
		fld.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a field from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getField:GUI_Field(name:string)
	
		return GUI_Field(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a text to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addText(name:string, visible:byte = false)
	
		local text:GUI_Text = new GUI_Text;
		
		text.m_type = GADGET_TEXT;
		text.m_name = name;
		text.m_visible = visible;
		text.m_layer = self;
		
		m_gadgetList.addLast(text);
		m_gadgetListReversed.addFirst(text);
		m_gadgetMap.insert(name, text);
		
		text.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a text from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getText:GUI_Text(name:string)
	
		return GUI_Text(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a button to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addButton(name:string, visible:byte = false)
	
		local button:GUI_Button = new GUI_Button;
		
		button.m_type = GADGET_BUTTON;
		button.m_name = name;
		button.m_visible = visible;
		button.m_layer = self;
		
		m_gadgetList.addLast(button);
		m_gadgetListReversed.addFirst(button);
		m_gadgetMap.insert(name, button);
		
		button.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a button from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getButton:GUI_Button(name:string)
	
		return GUI_Button(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a image to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addImage(name:string, visible:byte = false)
	
		local image:GUI_Image = new GUI_Image;
		
		image.m_type = GADGET_IMAGE;
		image.m_name = name;
		image.m_visible = visible;
		image.m_layer = self;
		
		m_gadgetList.addLast(image);
		m_gadgetListReversed.addFirst(image);
		m_gadgetMap.insert(name, image);
		
		image.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a image from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getImage:GUI_Image(name:string)
	
		return GUI_Image(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a checkbox to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addCheckbox(name:string, visible:byte = false)
	
		local checkbox:GUI_Checkbox = new GUI_Checkbox;
		
		checkbox.m_type = GADGET_CHECKBOX;
		checkbox.m_name = name;
		checkbox.m_visible = visible;
		checkbox.m_layer = self;
		
		m_gadgetList.addLast(checkbox);
		m_gadgetListReversed.addFirst(checkbox);
		m_gadgetMap.insert(name, checkbox);
		
		checkbox.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a checkbox from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getCheckbox:GUI_Checkbox(name:string)
	
		return GUI_Checkbox(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a form to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addForm(name:string, visible:byte = false)
	
		local form:GUI_Form = new GUI_Form;
		
		form.m_type = GADGET_FORM;
		form.m_name = name;
		form.m_visible = visible;
		form.m_layer = self;
		
		m_gadgetList.addLast(form);
		m_gadgetListReversed.addFirst(form);
		m_gadgetMap.insert(name, form);
		
		form.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getForm:GUI_Form(name:string)
	
		return GUI_Form(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a menu to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addMenu(name:string, visible:byte = false)
	
		local menu:GUI_Menu = new GUI_Menu;
		
		menu.m_type = GADGET_MENU;
		menu.m_name = name;
		menu.m_visible = visible;
		menu.m_layer = self;
		
		m_gadgetList.addLast(menu);
		m_gadgetListReversed.addFirst(menu);
		m_gadgetMap.insert(name, menu);
		
		menu.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a menu the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getMenu:GUI_Menu(name:string)
	
		return GUI_Menu(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a list to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addList(name:string, visible:byte = false)
	
		local list:GUI_List = new GUI_List;
		
		list.m_type = GADGET_LIST;
		list.m_name = name;
		list.m_visible = visible;
		list.m_layer = self;
		
		m_gadgetList.addLast(list);
		m_gadgetListReversed.addFirst(list);
		m_gadgetMap.insert(name, list);
		
		list.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a list from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getList:GUI_List(name:string)
	
		return GUI_List(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Add a slider to the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method addSlider(name:string, visible:byte = false)
	
		local slider:GUI_Slider = new GUI_Slider;
		
		slider.m_type = GADGET_SLIDER;
		slider.m_name = name;
		slider.m_visible = visible;
		slider.m_layer = self;
		
		m_gadgetList.addLast(slider);
		m_gadgetListReversed.addFirst(slider);
		m_gadgetMap.insert(name, slider);
		
		slider.m_gadgetListLink = m_gadgetList.lastLink();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Return a pointer to a slider from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method getSlider:GUI_Slider(name:string)
	
		return GUI_Slider(m_gadgetMap.valueForKey(name));
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Remove a gadget from the gadget containers.
	'// -------------------------------------------------------------------------------------------------------------
	method removeGadget:GUI_Gadget(name:string)
	
		local gadget:GUI_Gadget = GUI_Gadget(m_gadgetMap.valueForKey(name));
		gadget.m_gadgetListLink.remove();
		gadget.m_gadgetListReversedLink.remove();
		m_gadgetMap.remove(name);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the visibility of the layer.
	'// -------------------------------------------------------------------------------------------------------------
	method setVisibility(visible:byte)
	
		m_visible = visible;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set whether or not to use a background color.
	'// -------------------------------------------------------------------------------------------------------------
	method setBackgroundColorUsage(use:byte)
	
		m_useBackgroundColor = use;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the background color.
	'// -------------------------------------------------------------------------------------------------------------
	method setBackgroundColor(r:byte, g:byte, b:byte)
	
		m_backgroundColorR = r;
		m_backgroundColorG = g;
		m_backgroundColorB = b;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the transparency if this layer.
	'// -------------------------------------------------------------------------------------------------------------
	method setTransparency(alpha:double)
	
		m_transparency = alpha;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Activate this layer.
	'// -------------------------------------------------------------------------------------------------------------
	method activate()
	
		m_active = true;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Deactivate this layer.
	'// -------------------------------------------------------------------------------------------------------------
	method deactivate()
	
		m_active = false;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// The name of this layer.
	'// -------------------------------------------------------------------------------------------------------------
	field m_name:string;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Determines whether or not this layer is visible.
	'// -------------------------------------------------------------------------------------------------------------
	field m_visible:byte = false;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Determines whether or not this layer is active and can be interacted with.
	'// -------------------------------------------------------------------------------------------------------------
	field m_active:byte = false;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// The transparency of this layer. 1.0 is fully visible, while 0.0 is fully invisible.
	'// -------------------------------------------------------------------------------------------------------------
	field m_transparency:double = 1.0;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Determines whether or not to use a background color.
	'// -------------------------------------------------------------------------------------------------------------
	field m_useBackgroundColor:byte = false;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// What background color to use.
	'// -------------------------------------------------------------------------------------------------------------
	field m_backgroundColorR:byte = 0;
	field m_backgroundColorG:byte = 0;
	field m_backgroundColorB:byte = 0;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Containers for layers.
	'// -------------------------------------------------------------------------------------------------------------
	field m_gadgetList:TList = new TList;
	field m_gadgetListReversed:TList = new TList;
	field m_gadgetMap:TMap = new TMap;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Pointer to the links in the layer lists of the surface object this layer resides in.
	'// -------------------------------------------------------------------------------------------------------------
	field m_layerListLink:TLink;
	field m_layerListReversedLink:TLink;

end type
